package com.kexio.security.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.kexio.core.security.context.UserContext;
import com.kexio.core.security.context.UserContextHolder;
import com.kexio.security.domain.Permission;
import com.kexio.security.domain.Role;
import com.kexio.security.domain.User;
import com.kexio.security.domain.enums.UserStatus;
import com.kexio.security.service.PermissionRepository;
import com.kexio.security.service.RoleRepository;
import com.kexio.security.service.UserRepository;
import com.kexio.security.service.SecurityUserContextService;

/**
 * Security模块用户上下文服务实现
 * 
 * @author kexio
 */
@Service
public class SecurityUserContextServiceImpl implements SecurityUserContextService {

    private static final Logger log = LoggerFactory.getLogger(SecurityUserContextServiceImpl.class);

    private final UserRepository userRepository;
    private final RoleRepository roleRepository;
    private final PermissionRepository permissionRepository;

    public SecurityUserContextServiceImpl(UserRepository userRepository, 
                                         RoleRepository roleRepository,
                                         PermissionRepository permissionRepository) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.permissionRepository = permissionRepository;
    }

    @Override
    public UserContext loadUserContext(String username) {
        try {
            User user = userRepository.findByUsername(username).orElse(null);
            if (user == null) {
                log.debug("用户 {} 不存在", username);
                return null;
            }

            if (!UserStatus.ACTIVE.getCode().equals(user.getStatus())) {
                log.debug("用户 {} 状态不可用: {}", username, user.getStatus());
                return null;
            }

            return buildUserContext(user);
        } catch (Exception e) {
            log.error("加载用户上下文失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public UserContext loadUserContextById(Long userId) {
        try {
            User user = userRepository.findById(userId).orElse(null);
            if (user == null) {
                log.debug("用户ID {} 不存在", userId);
                return null;
            }

            if (!UserStatus.ACTIVE.getCode().equals(user.getStatus())) {
                log.debug("用户ID {} 状态不可用: {}", userId, user.getStatus());
                return null;
            }

            return buildUserContext(user);
        } catch (Exception e) {
            log.error("根据ID加载用户上下文失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public UserContext refreshUserPermissions(String username) {
        return loadUserContext(username);
    }

    @Override
    public boolean isUserLocked(String username) {
        try {
            User user = userRepository.findByUsername(username).orElse(null);
            return user != null && UserStatus.LOCKED.getCode().equals(user.getStatus());
        } catch (Exception e) {
            log.warn("检查用户锁定状态失败: {}", e.getMessage());
            return true; // 出现异常时默认认为已锁定
        }
    }

    @Override
    public UserContext loadUserDetails(String username) {
        return loadUserContext(username);
    }

    @Override
    public boolean initUserContext(String accessToken) {
        // TODO: 从访问令牌中解析用户信息并设置上下文
        log.debug("initUserContext with accessToken: {}", accessToken != null ? "***" : null);
        return true;
    }

    @Override
    public UserContext loadUserContext(Long userId) {
        return loadUserContextById(userId);
    }

    @Override
    public boolean refreshUserContext() {
        UserContext currentContext = UserContextHolder.getContext();
        if (currentContext != null && currentContext.getUsername() != null) {
            UserContext refreshedContext = loadUserContext(currentContext.getUsername());
            if (refreshedContext != null) {
                UserContextHolder.setContext(refreshedContext);
                return true;
            }
        }
        return false;
    }

    @Override
    public void updateUserContext(UserContext userContext) {
        UserContextHolder.setContext(userContext);
    }

    @Override
    public void mergeUserContext(UserContext additionalContext) {
        UserContext currentContext = UserContextHolder.getContext();
        if (currentContext == null) {
            UserContextHolder.setContext(additionalContext);
        } else if (additionalContext != null) {
            // 合并上下文信息
            if (additionalContext.getUserId() != null) {
                currentContext.setUserId(additionalContext.getUserId());
            }
            if (additionalContext.getUsername() != null) {
                currentContext.setUsername(additionalContext.getUsername());
            }
            if (additionalContext.getNickname() != null) {
                currentContext.setNickname(additionalContext.getNickname());
            }
            if (additionalContext.getEmail() != null) {
                currentContext.setEmail(additionalContext.getEmail());
            }
            if (additionalContext.getPhone() != null) {
                currentContext.setPhone(additionalContext.getPhone());
            }
            if (additionalContext.getRoles() != null && !additionalContext.getRoles().isEmpty()) {
                currentContext.setRoles(additionalContext.getRoles());
            }
            if (additionalContext.getPermissions() != null && !additionalContext.getPermissions().isEmpty()) {
                currentContext.setPermissions(additionalContext.getPermissions());
            }
            if (additionalContext.getTenantId() != null) {
                currentContext.setTenantId(additionalContext.getTenantId());
            }
            UserContextHolder.setContext(currentContext);
        }
    }

    @Override
    public void clearUserContext() {
        UserContextHolder.clear();
    }

    @Override
    public boolean isAuthenticated() {
        UserContext context = UserContextHolder.getContext();
        return context != null && context.getUserId() != null;
    }

    /**
     * 构建用户上下文
     * 
     * @param user 用户实体
     * @return 用户上下文
     */
    private UserContext buildUserContext(User user) {
        // 获取用户角色
        List<Role> roles = roleRepository.findByUserId(user.getId());
        List<String> roleCodes = roles.stream()
                .map(Role::getRoleCode)
                .collect(Collectors.toList());

        // 获取用户权限（包括角色权限和直接权限）
        List<Permission> permissions = permissionRepository.findByUserId(user.getId());
        List<String> permissionCodes = permissions.stream()
                .map(Permission::getPermissionCode)
                .collect(Collectors.toList());

        // 检查是否为超级管理员
        boolean isAdmin = roleCodes.contains("SUPER_ADMIN") || 
                         roleCodes.contains("admin") ||
                         roleCodes.contains("ADMIN");

        return UserContext.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .email(user.getEmail())
                .phone(user.getPhone())
                .avatar(user.getAvatar())
                .tenantId(user.getTenantId())
                .deptId(user.getDeptId())
                .roles(roleCodes)
                .permissions(permissionCodes)
                .isAdmin(isAdmin)
                .build();
    }
}
